home *** CD-ROM | disk | FTP | other *** search
- Path: vixen.cso.uiuc.edu!usenet
- From: n-dade@uiuc.edu
- Newsgroups: comp.lang.c++
- Subject: Q: when are temporaries constructed inside a :? destroyed
- Date: 16 Mar 1996 21:11:17 GMT
- Organization: University of Illinois at Urbana
- Message-ID: <4ifapl$2lq@vixen.cso.uiuc.edu>
- Reply-To: n-dade@uiuc.edu
- NNTP-Posting-Host: homer.apr.uiuc.edu
- X-Newsreader: IBM NewsReader/2 v1.2
-
-
- function( xyz ? abc : object1.GetCopyOfObject2().GetSomethingFromObject2() );
-
-
- I was debugging code like above and I realized that the compiler
- (IBM's VA C++) was destroying the temporary object generated during the
- evaluation of the ?: (there's a temporary "Object2") before the call to
- function(). I took the same code and compiled it on a different
- compiler (MS's C++) and the code it generated saved the direction of the
- ?: in another temporary variable, and destroyed the temporary object at
- after the call to function()cout if the temporary object had been
- constructed.
-
- I had expected the second behavior, but I can't find anything
- in my C++ references that defines which behavior is legal.
-
- Here's the code I used to test this:
-
- /*-----------------------------------------------------------*/
-
- #include "iostream.h"
- #include "string.h"
-
- class A { // a "string" class
- char* text;
- public:
- A(const char* t) {
- cout << "A(\"" << t << "\")" << endl;
- int len = strlen(t);
- text = new char[len+1];
- strncpy(text,t,len+1);
- }
-
- A(const A& a) {
- cout << "A(A&) (\"" << a.text << "\")" << endl;
- int len = strlen(a.text);
- text = new char[len+1];
- strncpy(text,a.text,len+1);
- }
-
- ~A() {
- static char c = 'A';
- cout << "~A() using " << c << endl;
- // instead of deleting the text I fill it with a known pattern
- // that way I can tell if something below uses this "freed" memory
- for(int i=0; text[i]; i++) text[i] = c;
- c++;
- }
-
- const char* QueryText() const { return text; } // return pointer to private char[]
- };
-
- class B { // something that has a "string" in it
- A a;
- public:
- B(const char* str) : a(str) {}
-
- A QueryA() const { return a; } // ask for its string
- };
-
- main(int argc, char *argv[])
- {
- // create a B
- B b ("some text");
-
- // and output its string if no arguments were given
- cout << ( argc>1 ? "argc was > 1" : b.QueryA().QueryText() )
- << endl;
-
- return 0;
- }
-
- /*-----------------------------------------------------------*/
-
- The statement of interest is the cout in main(): The first compiler
- generates:
-
- make room on stack for a char* named "temp1"
- if argc > 1 {
- temp1 = "argc was > 1";
- } else {
- make room on stack for an A named "temp2"
- pass &temp2 to b.QueryA() so QueryA constructs temp2 using A(const A& b.a)
- temp1 = temp2.QueryText()
- destroy temp2 using ~A()
- pop the room for temp2 off the stack
- }
- operator<< (ostream& cout, const char* temp1)
-
- So the output is:
- A("some text")
- A(A&) ("some text")
- ~A() using A
- AAAAAAAAA
- ~A() using B
-
-
- The second compiler generates:
-
- make room on stack for a char* named "temp1" an A named "temp2"
- and an int named "temp3"
- temp3 = (argc > 1)
- if temp3 {
- temp1 = "argc was > 1";
- } else {
- pass &temp2 to b.QueryA() so QueryA constructs temp2 using A(const A& b.a)
- temp1 = temp2.QueryText()
- }
- operator<< (ostream& cout, const char* temp1)
- if (temp3) {
- destroy temp2 using ~A()
- }
- pop temp1, 2 and 3 off the stack
-
- So the output is:
- A("some text")
- A(A&) ("some text")
- some text
- ~A() using A
- ~A() using B
-
-
- Which is the correct behavior? Or are they both considered correct?
-
- -Nicolas Dade / n9rzb / nicolas-dade@uiuc.edu
-
-